package org.dtrd.modules.content.tags.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dtrd.modules.content.tags.entity.bean.TagGroupInfo;
import org.dtrd.modules.content.tags.entity.bean.TagsDetail;
import org.dtrd.modules.content.tags.entity.bean.TagsListInfo;
import org.dtrd.modules.content.tags.entity.po.DtrdExtEmsYwTagCategory;
import org.dtrd.modules.content.tags.entity.po.DtrdExtEmsYwTags;
import org.dtrd.modules.patient.entity.po.DtrdRlPatientTag;
import org.dtrd.modules.content.tags.entity.request.TagsPageRequest;
import org.dtrd.modules.content.tags.mapper.DtrdExtEmsYwTagsMapper;
import org.dtrd.modules.content.tags.service.IDtrdExtEmsYwTagCategoryService;
import org.dtrd.modules.content.tags.service.IDtrdExtEmsYwTagsService;
import org.dtrd.modules.patient.service.IDtrdRlPatientTagService;
import org.dtrd.common.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * <p>
 * 标签 服务实现类
 * </p>
 *
 * @author QR
 * @since 2022-03-15
 */
@DS("multi-datasource1")
@Service
public class DtrdExtEmsYwTagsServiceImpl extends ServiceImpl<DtrdExtEmsYwTagsMapper, DtrdExtEmsYwTags> implements IDtrdExtEmsYwTagsService {


    @Autowired
    private IDtrdExtEmsYwTagCategoryService tagCategoryService;
    @Autowired
    private IDtrdRlPatientTagService patientTagService;

    @Override
    public List<TagsListInfo> getTagsList(String tagName, Integer tagType) {
        LambdaQueryWrapper<DtrdExtEmsYwTags> queryWrapper = baseQueryWrapper();
        if (StrUtil.isNotBlank(tagName)) {
            queryWrapper.like(DtrdExtEmsYwTags::getTagName, StringUtil.fuzzySearchWrapper(tagName));
        }
        if (tagType != null) {
            queryWrapper.eq(DtrdExtEmsYwTags::getTagType, tagType);
        }
        List<DtrdExtEmsYwTags> poList = list(queryWrapper);
        List<TagsListInfo> dtoList = new ArrayList<>(poList.size());
        if (!poList.isEmpty()) {
            Map<Integer, String> categoryIdToName = tagCategoryService.getTagCategoryIdToName();
            dtoList = poList.stream().map(p -> {
                TagsListInfo tagInfo = new TagsListInfo(p);
                Integer type = tagInfo.getTagType();
                if (type != null && categoryIdToName.containsKey(type)) {
                    String name = categoryIdToName.get(type);
                    tagInfo.setTagTypeName(name);
                }
                return tagInfo;
            }).collect(Collectors.toList());
        }
        return dtoList;
    }

    @Override
    public List<TagsListInfo> listTagsByTagType(Integer tagType, String tagName) {
        LambdaQueryWrapper<DtrdExtEmsYwTags> wrapper = Wrappers.lambdaQuery(DtrdExtEmsYwTags.class)
                .eq(DtrdExtEmsYwTags::getTagType, tagType);
        List<DtrdExtEmsYwTags> tags = baseMapper.selectList(wrapper);
        return Optional.ofNullable(tags)
                .map(t -> t.stream().map(TagsListInfo::new).collect(Collectors.toList()))
                .orElse(null);
    }

    @Override
    public List<String> getPatientTags(Integer patientId) {
        return baseMapper.selectPatientTags(patientId);
    }

    @Override
    public boolean hasLinkTag(Integer tagCategoryId) {
        LambdaQueryWrapper<DtrdExtEmsYwTags> wrapper = Wrappers.lambdaQuery(DtrdExtEmsYwTags.class)
                .eq(DtrdExtEmsYwTags::getTagType, tagCategoryId)
                .last("limit 1");
        DtrdExtEmsYwTags one = getOne(wrapper);
        return one != null;
    }

    @Override
    public IPage<TagsListInfo> pageTags(TagsPageRequest request) {
        LambdaQueryWrapper<DtrdExtEmsYwTags> queryWrapper = baseQueryWrapper();
        IPage<DtrdExtEmsYwTags> page = new Page<>(request.getPageNum(), request.getPageSize());
        page = this.page(page, queryWrapper);
        return page.convert(TagsListInfo::new);
    }

    @Override
    public boolean saveOrUpdateTags(TagsDetail dto) {
        DtrdExtEmsYwTags dtrdExtEmsYwTags = new DtrdExtEmsYwTags();
        if(dto.getTagId() == null){
            dtrdExtEmsYwTags = dtrdExtEmsYwTags.init();
        }
        dtrdExtEmsYwTags.parseFromDTO(dto);
        return saveOrUpdate(dtrdExtEmsYwTags);
    }

    @Override
    public boolean removeTags(Integer tagId) {
        // 删除关系表中的记录
        LambdaQueryWrapper<DtrdRlPatientTag> wrapper = Wrappers.lambdaQuery(DtrdRlPatientTag.class)
                .eq(DtrdRlPatientTag::getTagId, tagId);
        patientTagService.remove(wrapper);
        return removeById(tagId);
    }

    @Override
    public List<TagGroupInfo> listTags(Integer pid) {
        Map<Integer, String> tagCategoryIdToName = tagCategoryService.getTagCategoryIdToName();
        // 获取某个总分类下的所有子分类
        LambdaQueryWrapper<DtrdExtEmsYwTagCategory> wrapper = Wrappers.lambdaQuery(DtrdExtEmsYwTagCategory.class)
                .eq(DtrdExtEmsYwTagCategory::getCategoryPid, pid);
        List<DtrdExtEmsYwTagCategory> categories = tagCategoryService.list(wrapper);
        // 获取子分类下的所有表亲
        List<TagGroupInfo> list = null;
        if (CollectionUtil.isNotEmpty(categories)) {
            list = new ArrayList<>(categories.size());
            for (DtrdExtEmsYwTagCategory category : categories) {
                TagGroupInfo tagGroupInfo = new TagGroupInfo().parseFromPO(category);
                LambdaQueryWrapper<DtrdExtEmsYwTags> queryWrapper = Wrappers.lambdaQuery(DtrdExtEmsYwTags.class)
                        .eq(DtrdExtEmsYwTags::getTagType, category.getDataId());
                List<DtrdExtEmsYwTags> tags = list(queryWrapper);
                if (CollectionUtil.isNotEmpty(tags)) {
                    tagGroupInfo.setChildren(tags.stream().map(TagGroupInfo::new)
                            .collect(Collectors.toList()));
                }
                list.add(tagGroupInfo);
            }
        }
        return list;
    }

    private LambdaQueryWrapper<DtrdExtEmsYwTags> baseQueryWrapper() {
        return Wrappers.lambdaQuery(DtrdExtEmsYwTags.class)
                        .eq(DtrdExtEmsYwTags::getIsDel, 0);
    }

    private LambdaUpdateWrapper<DtrdExtEmsYwTags> baseUpdateWrapper() {
        return Wrappers.lambdaUpdate(DtrdExtEmsYwTags.class)
                        .eq(DtrdExtEmsYwTags::getIsDel, 0);
    }
}
